package com.swak.consistency;

import com.swak.consistency.core.aspect.ConsistencyProceeding;
import com.swak.consistency.core.context.ConsistencyContext;
import com.swak.consistency.core.handle.ConsistencyHandler;
import com.swak.consistency.core.resolve.ContextResolver;

/**
 * 一致性事件总入口
 * 
 * @author DELL
 */
public class ConsistencyLauncher {

	private static ConsistencyHandler<ConsistencyContext> Consistency_Handler;
	private static ContextResolver<ConsistencyContext> Context_Resolver;

	public ConsistencyLauncher(ConsistencyHandler<ConsistencyContext> consistencyHandler,
			ContextResolver<ConsistencyContext> contextResolver) {
		Consistency_Handler = consistencyHandler;
		Context_Resolver = contextResolver;
	}

	/**
	 * 准备阶段
	 * 
	 * @param context
	 * @return
	 * @throws Throwable
	 */
	public static Object prepare(ConsistencyProceeding proceeding) throws Throwable {
		ConsistencyContext context = ConsistencyContext.get(proceeding.getScheme());
		return ConsistencyLauncher.Consistency_Handler.prepare(context.setProceeding(proceeding));
	}

	/**
	 * 准备阶段
	 * 
	 * @param context
	 * @return
	 * @throws Throwable
	 */
	public static Object transmit(ConsistencyProceeding proceeding) throws Throwable {
		ConsistencyContext context = ConsistencyContext.get(proceeding.getScheme()).setProceeding(proceeding);
		Context_Resolver.transmit(context);
		return ConsistencyLauncher.Consistency_Handler.transmit(context);
	}

	/**
	 * 完成阶段
	 * 
	 * @param context
	 * @return
	 * @throws Throwable
	 */
	public static Object complete(ConsistencyProceeding proceeding) throws Throwable {
		ConsistencyContext context = ConsistencyLauncher.Context_Resolver.acquire(proceeding)
				.setPropagation(proceeding.getPropagation()).setScheme(proceeding.getScheme())
				.setProceeding(proceeding);
		return context.execute(() -> {
			return ConsistencyLauncher.Consistency_Handler.complete(context);
		});
	}
}
